﻿using EPiServer.Common.Security;
using EPiServer.Community.Blog;
using JoelAbrahamsson.TestUtilities;
using Moq;
using StructureMap.AutoMocking;
using Xunit;

namespace JoelAbrahamsson.MetaWeblog.Tests
{
    public class GetPostTests
    {
        [Fact]
        public void GetPost_ValidatesUser()
        {
            string username = RandomValues.String;
            string password = RandomValues.String;
            int postID = 1;
            Blog postsBlog = CreateFakeBlog();
            Mock<Entry> fakeEntry = CreateFakeEntry(postsBlog);
            Mock<MetaWeblogHandler> partiallyFakedMetaWeblogHandler =
                CreatePartiallyFakedMetaWeblogHandler(postsBlog, postID, fakeEntry);

            partiallyFakedMetaWeblogHandler.Object.GetPost(postID.ToString(), username, password);

            partiallyFakedMetaWeblogHandler.Verify(handler => handler.GetValidatedUser(postsBlog, username, password));
        }

        [Fact]
        public void GivenPostID_GetPost_ReturnsPost()
        {
            string username = RandomValues.String;
            string password = RandomValues.String;
            int postID = 1;
            Blog postsBlog = CreateFakeBlog();
            Mock<Entry> fakeEntry = CreateFakeEntry(postsBlog);
            Mock<MetaWeblogHandler> partiallyFakedMetaWeblogHandler = 
                CreatePartiallyFakedMetaWeblogHandler(postsBlog, postID, fakeEntry);

            Post returnedPost = partiallyFakedMetaWeblogHandler.Object.GetPost(postID.ToString(), username, password);
            
            Assert.NotNull(returnedPost);
            Assert.Equal<string>(fakeEntry.Object.Title, returnedPost.title);
            Assert.Equal<string>(fakeEntry.Object.Content, returnedPost.description);
        }

        private Blog CreateFakeBlog()
        {
            return new Mock<Blog>().Object;
        }

        private Mock<Entry> CreateFakeEntry(Blog postsBlog)
        {
            var fakeEntry = new Mock<Entry>();
            fakeEntry.SetupGet(entry => entry.Blog).Returns(postsBlog);
            fakeEntry.Setup(entry => entry.Clone()).Returns(fakeEntry.Object);
            fakeEntry.CallBase = true;
            fakeEntry.Object.Title = RandomValues.String;
            fakeEntry.Object.Content = RandomValues.String;
            return fakeEntry;
        }

        private Mock<MetaWeblogHandler> CreatePartiallyFakedMetaWeblogHandler(Blog postsBlog, int postID, Mock<Entry> fakeEntry)
        {
            MoqAutoMocker<MetaWeblogHandler> metaWebLogHandlerAutoMocker = new MoqAutoMocker<MetaWeblogHandler>();
            metaWebLogHandlerAutoMocker.PartialMockTheClassUnderTest();
            Mock<MetaWeblogHandler> partiallyFakedMetaWeblogHandler = Mock.Get(metaWebLogHandlerAutoMocker.ClassUnderTest);
            IUser fakeUser = new Mock<IUser>().Object;
            partiallyFakedMetaWeblogHandler.Setup(handler => handler.GetEntry(postID.ToString())).Returns(fakeEntry.Object);
            partiallyFakedMetaWeblogHandler.Setup(
                handler => handler.GetValidatedUser(postsBlog, It.IsAny<string>(), It.IsAny<string>())).Returns(fakeUser);
            return partiallyFakedMetaWeblogHandler;
        }
    }
}
